﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using Sunny.UI;
using Sunny.UI.Win32;
using System.Collections;

namespace MySerialPort
{
    public partial class CSerialPort : UIForm
    {
        public static SerialPort m_serialPort = new SerialPort();
        
        public CSerialPort()
        {
            InitializeComponent(); 
        }

        private void m_btnSearch_Click(object sender, EventArgs e)
        {
            try
            {
                string[] items = SerialPort.GetPortNames();
                m_ctrlPort.Items.Clear();
                m_ctrlPort.Items.AddRange(items);
                m_ctrlPort.SelectedIndex = m_ctrlPort.Items.Count > 0 ? 0 : -1;

                if (items.Length > 0)
                {
                    m_ctrlBaud.SelectedIndex = 10;
                    m_ctrlData.SelectedIndex = 0;
                    m_ctrlStop.SelectedIndex = 0;
                    m_ctrlProof.SelectedIndex = 0;
                }
                else
                {
                    MessageBox.Show("当前无串口连接！");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("无串口设备!/r/n请检查是否连接设备!/r/n请检查设备驱动!");
            }
        }

        private void m_btnConnect_Click(object sender, EventArgs e)
        {
            if (!m_serialPort.IsOpen)
            {
                if (m_ctrlPort.SelectedItem == null)
                {
                    MessageBox.Show("请选择正确的串口", "提示");
                    return;
                }
                // 设置串口参数
                m_serialPort.PortName = m_ctrlPort.Text.ToString();
                m_serialPort.BaudRate = Convert.ToInt32(m_ctrlBaud.SelectedItem.ToString());
                m_serialPort.DataBits = Convert.ToInt32(m_ctrlData.SelectedItem.ToString());

                // 设置停止位
                if (m_ctrlStop.Text == "One")
                {
                    m_serialPort.StopBits = StopBits.One;
                }
                else if (m_ctrlStop.Text == "Two")
                {
                    m_serialPort.StopBits = StopBits.Two;
                }
                else if (m_ctrlStop.Text == "OnePointTwo")
                {
                    m_serialPort.StopBits = StopBits.OnePointFive;
                }
                else if (m_ctrlStop.Text == "None")
                {
                    m_serialPort.StopBits = StopBits.None;
                }

                // 设置奇偶校验位
                if (m_ctrlProof.Text == "Odd")
                {
                    m_serialPort.Parity = Parity.Odd;
                }
                else if (m_ctrlProof.Text == "Even")
                {
                    m_serialPort.Parity = Parity.Even;
                }
                else if (m_ctrlProof.Text == "None")
                {
                    m_serialPort.Parity = Parity.None;
                }

                try
                {
                    m_ctrlPort.Enabled = false;
                    m_ctrlBaud.Enabled = false;
                    m_ctrlData.Enabled = false;
                    m_ctrlStop.Enabled = false;
                    m_ctrlProof.Enabled = false;
                    m_btnSearch.Enabled = false;

                    m_serialPort.Open();
                    m_btnConnect.Text = "断开";
                    m_Led.OnColor = Color.FromArgb(110, 190, 40);

                }
                catch (Exception ex)
                {
                    MessageBox.Show("串口打开失败！");
                }
               
                m_serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialDataReceive);
            }
            else if (m_btnConnect.Text == "断开")
            {
                m_ctrlPort.Enabled = true;
                m_ctrlBaud.Enabled = true;
                m_ctrlData.Enabled = true;
                m_ctrlStop.Enabled = true;
                m_ctrlProof.Enabled = true;
                m_btnSearch.Enabled = true;

                m_serialPort.DiscardInBuffer();
                m_serialPort.Close();
                m_btnConnect.Text = "连接";
                m_Led.OnColor = Color.Red;
            }
        }

        private void m_btnClearRecv_Click(object sender, EventArgs e)
        {
            m_tbReceive.Clear();
        }

        private void m_btnSend_Click(object sender, EventArgs e)
        {
            if (m_serialPort.IsOpen)
            {
                string strData = m_tbSend.Text;
                int nBufferLen = strData.Length;
                byte[] sendData = new Byte[nBufferLen];
                if (uiRB_ASCII_Send.Checked)
                {
                    sendData = System.Text.Encoding.Default.GetBytes(strData);//转码
                }
                else if(uiRB_HEX_Send.Checked)
                {
                    // 使用UTF8编码将字符串转换为字节数组
                    sendData = Encoding.UTF8.GetBytes(strData);
                }

                try
                {
                    // 写数据
                    m_serialPort.Write(sendData, 0, sendData.Length);
                    Task.Run(() => PrintfData(sendData, sendData.Length, 0));
                }
                catch
                {
                    MessageBox.Show("发送失败！");
                }

            }
            else
            {
                MessageBox.Show("串口未打开！");
            }
        }

        private void m_btnClearSend_Click(object sender, EventArgs e)
        {
            m_tbSend.Clear();
        }

        private void CSerialPort_Load(object sender, EventArgs e)
        {
            // 设置窗体边框样式为可调整大小
            this.FormBorderStyle = FormBorderStyle.Sizable;

            this.CenterToScreen();
            m_btnConnect.Text = "连接";
            m_Led.OnColor = Color.Red;
            m_tbReceive.Padding = new Padding(0, 0, 0, 0); // 根据需要调整这些值
            uiRB_ASCII_Send.Checked = true;
            uiRB_ASCII_Recv.Checked = true;

            try
            {
                string[] items = SerialPort.GetPortNames();
                m_ctrlPort.Items.AddRange(items);
                m_ctrlPort.SelectedIndex = m_ctrlPort.Items.Count > 0 ? 0 : -1;

                if (items.Length > 0)
                {
                    m_ctrlBaud.SelectedIndex = 10;
                    m_ctrlData.SelectedIndex = 0;
                    m_ctrlStop.SelectedIndex = 0;
                    m_ctrlProof.SelectedIndex = 0;
                }
                else
                {
                    MessageBox.Show("当前无串口连接！");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("无串口设备!/r/n请检查是否连接设备!/r/n请检查设备驱动!");
            }

        }

        #region(接收串口数据)
        // 串口缓冲区
        List<byte> pBuffer = new List<byte>(4096);
        // 串口缓冲区最大字节数
        int nBufferMaxSize = 4096;

        private void SerialDataReceive(object sender, SerialDataReceivedEventArgs e)
        {
            if (m_serialPort.IsOpen == false)
            {
                m_serialPort.Close();
                return;
            }

            // 读取缓存的数据长度
            int nByteLen = m_serialPort.BytesToRead;
            byte [] bRecv = new byte[nByteLen];
            // 将读取的数据存入缓存数组中
            m_serialPort.Read(bRecv,0,nByteLen);
            // 缓存数超过总的字节数，则丢弃前面的数据

            pBuffer.Clear();
            // 将接收的数据存入缓冲区
            pBuffer.AddRange(bRecv);

            byte[] rBuffer = new byte[9192];
            pBuffer.CopyTo(0, rBuffer, 0, pBuffer.Count);
            Task.Run(() =>
            PrintfData(rBuffer, pBuffer.Count, 1));

        }
        #endregion

        #region (打印数据)
        void PrintfData(byte[] buffer,int nLength,int nTR)
        {
            Int16 nLen;
            StringBuilder sb = new StringBuilder();
            if (nTR == 0)
                sb.Append("发送:");
            else
                sb.Append("接收:");


            string strRecv = "";
            if (uiRB_ASCII_Recv.Checked)
            {
                strRecv = sb.ToString();
                strRecv += Encoding.Default.GetString(buffer);
            }
            else if(uiRB_HEX_Recv.Checked)
            {
                // 转为字节显示
                for (nLen = 0; nLen < nLength; nLen++)
                {
                    sb.Append(buffer[nLen].ToString());
                    sb.Append(" ");
                }
                strRecv = sb.ToString();
            }
            MethodInvoker mi = new MethodInvoker(()=>
            { 
                if(m_tbReceive.Lines.Count() > 20)
                    m_tbReceive.Clear();
                m_tbReceive.AppendText(strRecv + "\r\n");
            });
            BeginInvoke(mi);
        }
        #endregion

        private void uiButton_Close_Click(object sender, EventArgs e)
        {
            base.Close();
        }
    }
}
